package com.bloom.dao;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import com.bloom.entity.DisplayInfo;
import com.bloom.entity.ServiceProvider;
import com.bloom.entity.ServiceReceiver;
import com.bloom.entity.User;
import com.bloom.entity.UserTravelDetails;
import com.bloom.model.TravelInfo;
import com.bloom.util.FormToEntity;
import com.bloom.exception.UserExistsException;

public class TravelServiceDao {

	@PersistenceContext
	private EntityManager entityManager;

	@Autowired
	private StaticDataDao staticDataDao;

	public UserTravelDetails loadTravelDetails(TravelInfo travelInfo) {
		Query query = entityManager
				.createQuery("from UserTravelDetails utd where "
						+ "utd.dateTime=:datetime and utd.flightNo=:flightNo and utd.mode.id=:mode");
		UserTravelDetails travelDetails = FormToEntity
				.toUserTravelDetails(travelInfo);
		query.setParameter("mode", travelDetails.getMode().getId());
		query.setParameter("flightNo", travelDetails.getFlightNo());

		query.setParameter("datetime", travelDetails.getDateTime());
		List<UserTravelDetails> travelDetailList = query.getResultList();
		if (travelDetailList == null || travelDetailList.isEmpty()
				|| travelDetailList.size() > 1) {
			travelDetails = null;
		} else {
			travelDetails = travelDetailList.get(0);
		}
		return travelDetails;
	}

	public UserTravelDetails loadTravelDetails(int travelId) {
		Query query = entityManager
				.createQuery("from UserTravelDetails utd where "
						+ "utd.id=:tid");
		query.setParameter("tid", travelId);

		List<UserTravelDetails> travelDetailList = query.getResultList();
		UserTravelDetails travelDetails = null;
		if (travelDetailList == null || travelDetailList.isEmpty()
				|| travelDetailList.size() > 1) {
			travelDetails = null;
		} else {
			travelDetails = travelDetailList.get(0);
		}
		return travelDetails;
	}

	@Transactional
	public void saveTravelDetails(TravelInfo travelInfo) {
		UserTravelDetails travelDetails = FormToEntity
				.toUserTravelDetails(travelInfo);
		DisplayInfo mode = staticDataDao.getDisplayInfo(Integer
				.valueOf(travelDetails.getMode().getId()));

		travelDetails.setMode(mode);
		try {
			// entityManager.getTransaction().begin();
			entityManager.persist(travelDetails);
			// entityManager.getTransaction().commit();
		} finally {
			// entityManager.close();
		}
	}

	public List<ServiceProvider> loadServiceProviders(int travelId) {
		Query query = entityManager
				.createQuery("from ServiceProvider sp where "
						+ "sp.travelDetails.id=:travelId");
		query.setParameter("travelId", travelId);
		List<ServiceProvider> travelDetails = (List<ServiceProvider>) query
				.getResultList();
		return travelDetails;
	}

	@Transactional
	public void saveServiceProvider(int travelId, String username) {
		ServiceProvider serviceProvider = new ServiceProvider();// FormToEntity.toServiceProvider(travelId,
																// username);
		serviceProvider.setTravelDetails(loadTravelDetails(travelId));
		serviceProvider.setUser(loadUser(username));
		try {
			entityManager.persist(serviceProvider);
		} finally {
		}
	}

	private User loadUser(String username) {
		Query query = entityManager.createQuery("from User u where "
				+ "u.username=:username");
		query.setParameter("username", username);

		List<User> users = query.getResultList();
		User user = null;
		if (users == null || users.isEmpty() || users.size() > 1) {
			users = null;
		} else {
			user = users.get(0);
		}
		return user;
	}

	public List<ServiceReceiver> loadServiceReceivers(int travelId) {
		Query query = entityManager
				.createQuery("from ServiceReceiver sr where "
						+ "sr.travelDetails.id=:travelId");
		query.setParameter("travelId", travelId);
		List<ServiceReceiver> travelDetails = (List<ServiceReceiver>) query
				.getResultList();
		return travelDetails;
	}

	@Transactional
	public void saveServiceReceiver(int travelId, String username) {
		ServiceReceiver serviceReceiver = new ServiceReceiver();// FormToEntity.toServiceProvider(travelId,
																// username);
		serviceReceiver.setTravelDetails(loadTravelDetails(travelId));
		serviceReceiver.setUser(loadUser(username));
		try {
			// entityManager.getTransaction().begin();
			entityManager.persist(serviceReceiver);
			// entityManager.getTransaction().commit();
		} finally {
			// entityManager.close();
		}
	}

	@Transactional
	public void createUser(String username, String password)
			throws UserExistsException {
		User existingUser = loadUser(username);
		if (existingUser != null) {
			throw new UserExistsException();
		}
		User user = new User();
		user.setUsername(username);
		user.setPassword(password);
		user.setEnabled(true);
		entityManager.persist(user);
	}

	public void setStaticDataDao(StaticDataDao staticDataDao) {
		this.staticDataDao = staticDataDao;
	}
}
